/**
 * API 响应工具类
 * 统一处理所有接口的响应格式
 */

import { Response, Request } from 'express';
import {
  ErrorCodeUtils,
  ErrorResponse,
  SuccessResponse,
  ApiResponse,
  ERROR_CODES,
  COMMON_ERROR_CODES,
  BUSINESS_ERROR_CODES,
  AUTH_ERROR_CODES,
  VALIDATION_ERROR_CODES
} from './errorCodes';
import { LanguageType, DEFAULT_LANGUAGE } from '../config/languages';

/**
 * 响应工具类
 */
export class ResponseUtils {
  /**
   * 发送成功响应
   * @param res Express响应对象
   * @param data 响应数据
   * @param message 成功消息
   * @param statusCode HTTP状态码
   * @param language 语言代码
   */
  static success<T>(
    res: Response, 
    data: T, 
    message?: string, 
    statusCode: number = 200,
    language?: LanguageType
  ): void {
    const currentLanguage = language || DEFAULT_LANGUAGE;
    const response: SuccessResponse<T> = ErrorCodeUtils.getSuccess(data, message, currentLanguage);
    res.status(statusCode).json(response);
  }

  /**
   * 发送错误响应
   * @param res Express响应对象
   * @param errorCode 错误码
   * @param customMessage 自定义错误信息
   * @param statusCode HTTP状态码
   * @param details 错误详情
   * @param language 语言代码
   */
  static error(
    res: Response,
    errorCode: number,
    customMessage?: string,
    statusCode?: number,
    details?: any,
    language?: LanguageType
  ): void {
    const currentLanguage = language || DEFAULT_LANGUAGE;
    const errorResponse: ErrorResponse = ErrorCodeUtils.getError(errorCode, customMessage, currentLanguage);
    
    if (details) {
      errorResponse.details = details;
    }
    
    if (statusCode) {
      errorResponse.code = statusCode;
    }
    
    // 根据错误码确定HTTP状态码
    const httpStatus = statusCode || this.getHttpStatusByErrorCode(errorCode);
    
    res.status(httpStatus).json(errorResponse);
  }

  /**
   * 发送通用错误响应
   * @param res Express响应对象
   * @param errorCode 错误码常量
   * @param customMessage 自定义错误信息
   * @param statusCode HTTP状态码
   * @param details 错误详情
   * @param language 语言代码
   */
  static sendError(
    res: Response,
    errorCode: { code: number; message: string },
    customMessage?: string,
    statusCode?: number,
    details?: any,
    language?: LanguageType
  ): void {
    this.error(res, errorCode.code, customMessage || errorCode.message, statusCode, details, language);
  }

  /**
   * 发送客户端错误响应
   * @param res Express响应对象
   * @param message 错误信息
   * @param statusCode HTTP状态码
   */
  static badRequest(res: Response, message: string = '请求参数错误'): void {
    this.sendError(res, COMMON_ERROR_CODES.BAD_REQUEST, message, 400);
  }

  /**
   * 发送未授权错误响应
   * @param res Express响应对象
   * @param message 错误信息
   */
  static unauthorized(res: Response, message: string = '未授权访问'): void {
    this.sendError(res, COMMON_ERROR_CODES.UNAUTHORIZED, message, 401);
  }

  /**
   * 发送禁止访问错误响应
   * @param res Express响应对象
   * @param message 错误信息
   */
  static forbidden(res: Response, message: string = '禁止访问'): void {
    this.sendError(res, COMMON_ERROR_CODES.FORBIDDEN, message, 403);
  }

  /**
   * 发送资源不存在错误响应
   * @param res Express响应对象
   * @param message 错误信息
   */
  static notFound(res: Response, message: string = '资源不存在'): void {
    this.sendError(res, COMMON_ERROR_CODES.NOT_FOUND, message, 404);
  }

  /**
   * 发送冲突错误响应
   * @param res Express响应对象
   * @param message 错误信息
   */
  static conflict(res: Response, message: string = '资源冲突'): void {
    this.sendError(res, COMMON_ERROR_CODES.CONFLICT, message, 409);
  }

  /**
   * 发送服务器错误响应
   * @param res Express响应对象
   * @param message 错误信息
   */
  static internalError(res: Response, message: string = '服务器内部错误'): void {
    this.sendError(res, COMMON_ERROR_CODES.INTERNAL_SERVER_ERROR, message, 500);
  }

  /**
   * 发送用户相关错误响应
   * @param res Express响应对象
   * @param errorCode 用户错误码
   * @param customMessage 自定义错误信息
   */
  static userError(
    res: Response, 
    errorCode: keyof typeof BUSINESS_ERROR_CODES,
    customMessage?: string
  ): void {
    this.sendError(res, BUSINESS_ERROR_CODES[errorCode], customMessage);
  }

  /**
   * 发送认证相关错误响应
   * @param res Express响应对象
   * @param errorCode 认证错误码
   * @param customMessage 自定义错误信息
   */
  static authError(
    res: Response, 
    errorCode: keyof typeof AUTH_ERROR_CODES,
    customMessage?: string
  ): void {
    this.sendError(res, AUTH_ERROR_CODES[errorCode], customMessage);
  }

  /**
   * 发送验证相关错误响应
   * @param res Express响应对象
   * @param errorCode 验证错误码
   * @param customMessage 自定义错误信息
   */
  static validationError(
    res: Response, 
    errorCode: keyof typeof VALIDATION_ERROR_CODES,
    customMessage?: string
  ): void {
    this.sendError(res, VALIDATION_ERROR_CODES[errorCode], customMessage);
  }

  /**
   * 发送分页数据响应
   * @param res Express响应对象
   * @param data 数据列表
   * @param total 总数量
   * @param page 当前页码
   * @param limit 每页数量
   * @param message 成功消息
   */
  static paginated<T>(
    res: Response,
    data: T[],
    total: number,
    page: number,
    limit: number,
    message: string = '查询成功'
  ): void {
    const paginationData = {
      data,
      pagination: {
        total,
        page,
        limit,
        totalPages: Math.ceil(total / limit),
        hasNext: page < Math.ceil(total / limit),
        hasPrev: page > 1
      }
    };
    
    this.success(res, paginationData, message);
  }

  /**
   * 发送列表数据响应
   * @param res Express响应对象
   * @param data 数据列表
   * @param message 成功消息
   */
  static list<T>(res: Response, data: T[], message: string = '查询成功'): void {
    this.success(res, { data, total: data.length }, message);
  }

  /**
   * 发送创建成功响应
   * @param res Express响应对象
   * @param data 创建的数据
   * @param message 成功消息
   */
  static created<T>(res: Response, data: T, message: string = '创建成功'): void {
    this.success(res, data, message, 201);
  }

  /**
   * 发送更新成功响应
   * @param res Express响应对象
   * @param data 更新的数据
   * @param message 成功消息
   */
  static updated<T>(res: Response, data: T, message: string = '更新成功'): void {
    this.success(res, data, message);
  }

  /**
   * 发送删除成功响应
   * @param res Express响应对象
   * @param message 成功消息
   */
  static deleted(res: Response, message: string = '删除成功'): void {
    this.success(res, null, message);
  }

  /**
   * 根据错误码获取HTTP状态码
   * @param errorCode 错误码
   * @returns HTTP状态码
   */
  private static getHttpStatusByErrorCode(errorCode: number): number {
    if (errorCode >= 400 && errorCode < 500) {
      return errorCode;
    }
    
    if (errorCode >= 500 && errorCode < 600) {
      return errorCode;
    }
    
    // 业务错误码映射到HTTP状态码
    if (errorCode >= 1000 && errorCode < 2000) {
      // 业务错误通常返回400
      return 400;
    }
    
    if (errorCode >= 2000 && errorCode < 3000) {
      // 认证授权错误通常返回401或403
      return 401;
    }
    
    if (errorCode >= 3000 && errorCode < 4000) {
      // 验证错误返回400
      return 400;
    }
    
    if (errorCode >= 4000 && errorCode < 5000) {
      // 数据库错误返回500
      return 500;
    }
    
    if (errorCode >= 5000 && errorCode < 6000) {
      // 文件操作错误返回500
      return 500;
    }
    
    if (errorCode >= 6000 && errorCode < 7000) {
      // 第三方服务错误返回502
      return 502;
    }
    
    // 默认返回500
    return 500;
  }

  /**
   * 发送自定义响应
   * @param res Express响应对象
   * @param response 响应对象
   * @param statusCode HTTP状态码
   */
  static custom<T>(res: Response, response: ApiResponse<T>, statusCode?: number): void {
    const httpStatus = statusCode || this.getHttpStatusByErrorCode(response.code);
    res.status(httpStatus).json(response);
  }

  /**
   * 从请求对象获取语言并发送成功响应
   * @param req Express请求对象
   * @param res Express响应对象
   * @param data 响应数据
   * @param message 成功消息
   * @param statusCode HTTP状态码
   */
  static successWithLanguage<T>(
    req: Request,
    res: Response,
    data: T,
    message?: string,
    statusCode: number = 200
  ): void {
    const language = (req as any).language || DEFAULT_LANGUAGE;
    this.success(res, data, message, statusCode, language);
  }

  /**
   * 从请求对象获取语言并发送错误响应
   * @param req Express请求对象
   * @param res Express响应对象
   * @param errorCode 错误码
   * @param customMessage 自定义错误信息
   * @param statusCode HTTP状态码
   * @param details 错误详情
   */
  static errorWithLanguage(
    req: Request,
    res: Response,
    errorCode: number,
    customMessage?: string,
    statusCode?: number,
    details?: any
  ): void {
    const language = (req as any).language || DEFAULT_LANGUAGE;
    this.error(res, errorCode, customMessage, statusCode, details, language);
  }

  /**
   * 发送文件下载响应
   * @param res Express响应对象
   * @param filePath 文件路径
   * @param fileName 文件名
   */
  static download(res: Response, filePath: string, fileName?: string): void {
    if (fileName) {
      res.download(filePath, fileName);
    } else {
      res.download(filePath);
    }
  }

  /**
   * 发送文件流响应
   * @param res Express响应对象
   * @param filePath 文件路径
   * @param contentType 内容类型
   */
  static sendFile(res: Response, filePath: string, contentType?: string): void {
    if (contentType) {
      res.setHeader('Content-Type', contentType);
    }
    res.sendFile(filePath);
  }
}

// 导出常用的错误码常量，方便直接使用
export const {
  COMMON: COMMON_ERRORS,
  BUSINESS: BUSINESS_ERRORS,
  AUTH: AUTH_ERRORS,
  VALIDATION: VALIDATION_ERRORS
} = ERROR_CODES;

export default ResponseUtils; 